package cn.demoncat.util.lang;

import cn.demoncat.util.exception.BizRuntimeException;
import cn.demoncat.util.exception.ParamRuntimeException;
import cn.demoncat.util.lang.constant.StringConstant;
import com.alibaba.fastjson.util.TypeUtils;

import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * 通用对象工具
 * 
 * @author 延晓磊
 *
 * @since 2019年2月14日
 */
public final class ObjectUtil {

	/**
	 * 为空校验
	 *
	 * @param o
	 * @param <T>
	 * @return
	 *
	 * @author 延晓磊
	 * @since 2021年10月08日
	 */
	public static <T>T checkNull(T o) {
		ParamEmptyUtil.checkNull(o);
		return o;
	}

	/**
	 * 如果o非空，执行 consumer.accept(o)
	 *
	 * 例：ObjectUtil.ifNotNull(id, data::setId);
	 *
	 * @param o
	 * @param consumer
	 * @param <T>
	 */
	public static <T>void ifNotNull(T o, Consumer<T> consumer){
		OptionalUtil.consumer(o, consumer);
	}

	/**
	 * null转默认值
	 * 
	 * @param o
	 * @param def	默认值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年2月14日
	 */
	public static <T>T toDefault(T o, T def) {
		return o == null ? def : o;
	}

	/**
	 * null转默认值
	 *
	 * @param o
	 * @param def	默认值
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年2月14日
	 */
	public static <T>T toDefault(T o, Supplier<T> def) {
		return o == null ? def.get() : o;
	}
	
	/**
	 * null转空字符串
	 * 
	 * @param o
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年2月14日
	 */
	public static Object toEmpty(Object o) {
		return o == null ? StringConstant.EMPTY : o;
	}
	
	/**
	 * 获取对象，如果为NULL时抛异常
	 * 
	 * @param o
	 * @param msg	异常信息
	 * @return
	 * 
	 * @throws BizRuntimeException "msg"
	 * 
	 * @author 延晓磊
	 *
	 * @since 2018年6月5日
	 */
	public static <T>T toException(T o, String msg) {
		if (o == null) {
			throw new BizRuntimeException(msg);
		}else {
			return o;
		}
	}
	
	/**
	 * 获取对象，如果为空时抛异常
	 * 
	 * @param o
	 * @return
	 * 
	 * @throws ParamRuntimeException 参数为空
	 * 
	 * @author 延晓磊
	 *
	 * @since 2018年6月5日
	 */
	public static <T>T toException(T o) {
		if (o == null) {
			throw ParamRuntimeException.NULL;
		}else {
			return o;
		}
	}
	
	/**
	 * 转换为Map
	 * 
	 * @param o
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年4月18日
	 */
	public static Map<String,Object> toMap(Object o){
		return ReflectUtil.toMap(o);
	}
	
	/**
	 * 转换为Map
	 * 
	 * @param o	对象
	 * @param excludeNull	是否排除数据源的null值：true 字段值为null时忽略
	 * 
	 * @return	Map 所有实例字段，包含继承字段
	 * 
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年9月25日
	 */
	public static Map<String, Object> toMap(Object o, boolean excludeNull) {
		return ReflectUtil.toMap(o, excludeNull);
	}
	
	/**
	 * 转换为Map
	 * 
	 * @param o
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年4月18日
	 */
	public static Map<String, String> toStrMap(Object o) {
		return ReflectUtil.toStrMap(o);
	}
	
	/**
	 * 转换为Map
	 * 
	 * @param o	对象
	 * @param excludeNull	是否排除数据源的null/""值：true 字段值为null/""时忽略
	 * 
	 * @return	Map 所有实例字段，包含继承字段
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年9月25日
	 */
	public static Map<String, String> toStrMap(Object o, boolean excludeNull) {
		return ReflectUtil.toStrMap(o,excludeNull);
	}

	/**
	 * 类型转换
	 *
	 * @param obj
	 * @param clazz
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年9月25日
	 */
	public static <T> T cast(Object obj, Class<T> clazz) {
		return TypeUtils.castToJavaBean(obj, clazz);
	}
}
